/**
 * 请求防护工具
 * 用于防止重复API请求，特别是在React Strict Mode下的双重调用
 */

interface RequestGuard {
  isLoading: boolean;
  lastRequestTime: number;
  requestId: string | null;
}

class RequestGuardManager {
  private guards: Map<string, RequestGuard> = new Map();
  private readonly MIN_INTERVAL = 100; // 最小请求间隔（毫秒）

  /**
   * 检查是否可以发送请求
   */
  canRequest(key: string, params?: any): boolean {
    const guard = this.guards.get(key);
    const now = Date.now();
    
    // 生成请求ID（基于参数）
    const requestId = this.generateRequestId(params);
    
    if (!guard) {
      // 首次请求
      this.guards.set(key, {
        isLoading: true,
        lastRequestTime: now,
        requestId,
      });
      return true;
    }
    
    // 检查是否正在加载
    if (guard.isLoading) {
      return false;
    }
    
    // 检查时间间隔
    if (now - guard.lastRequestTime < this.MIN_INTERVAL) {
      return false;
    }
    
    // 检查请求ID是否相同（防止相同参数的重复请求）
    if (guard.requestId === requestId && now - guard.lastRequestTime < 1000) {
      return false;
    }
    
    // 更新防护状态
    guard.isLoading = true;
    guard.lastRequestTime = now;
    guard.requestId = requestId;
    
    return true;
  }

  /**
   * 标记请求完成
   */
  completeRequest(key: string): void {
    const guard = this.guards.get(key);
    if (guard) {
      guard.isLoading = false;
    }
  }

  /**
   * 清除防护状态
   */
  clearGuard(key: string): void {
    this.guards.delete(key);
  }

  /**
   * 清除所有防护状态
   */
  clearAll(): void {
    this.guards.clear();
  }

  /**
   * 生成请求ID
   */
  private generateRequestId(params?: any): string {
    if (!params) return 'no-params';
    
    try {
      return JSON.stringify(params);
    } catch {
      return String(params);
    }
  }

  /**
   * 获取防护状态
   */
  getGuardStatus(): Record<string, RequestGuard> {
    const status: Record<string, RequestGuard> = {};
    this.guards.forEach((guard, key) => {
      status[key] = { ...guard };
    });
    return status;
  }

  /**
   * 强制重置防护状态（用于调试）
   */
  forceReset(key: string): void {
    const guard = this.guards.get(key);
    if (guard) {
      guard.isLoading = false;
      guard.lastRequestTime = 0;
      guard.requestId = null;
    }
  }
}

// 创建全局实例
export const requestGuard = new RequestGuardManager();

// 在开发环境下暴露到window对象
if (process.env.NODE_ENV === 'development') {
  (window as any).requestGuard = requestGuard;
}

/**
 * 请求防护装饰器
 */
export function withRequestGuard<T extends (...args: any[]) => Promise<any>>(
  key: string,
  fn: T
): T {
  return (async (...args: any[]) => {
    const params = args[0]; // 假设第一个参数是请求参数
    
    if (!requestGuard.canRequest(key, params)) {
      return Promise.resolve(); // 静默返回，不执行请求
    }
    
    try {
      const result = await fn(...args);
      return result;
    } finally {
      requestGuard.completeRequest(key);
    }
  }) as T;
}
